/*	--- 模块管理 --- 

在软件开发中，把一个大项目分拆为多个模块是降低软件复杂度的有效方法：

                        ┌ ─ ─ ─ ─ ─ ─ ┐
                          ┌─────────┐
                        │ │Module A │ │
                          └─────────┘
┌──────────────┐ split  │ ┌─────────┐ │
│Single Project│───────>  │Module B │
└──────────────┘        │ └─────────┘ │
                          ┌─────────┐
                        │ │Module C │ │
                          └─────────┘
                        └ ─ ─ ─ ─ ─ ─ ┘


对于Maven工程来说，原来是一个大项目：

	single-project
	├── pom.xml
	└── src


现在可以分拆成3个模块：

	mutiple-project
	├── module-a
	│   ├── pom.xml
	│   └── src
	├── module-b
	│   ├── pom.xml
	│   └── src
	└── module-c
	    ├── pom.xml
	    └── src


Maven可以有效地管理多个模块，我们只需要把每个模块当作一个独立的Maven项目，它们有各自独立的pom.xml。

例如，模块A的pom.xml：  */
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itranswarp.learnjava</groupId>
    <artifactId>module-a</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging> // <-- module中的packaging

    <name>module-a</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.28</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.5.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>



// 模块B的pom.xml：
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itranswarp.learnjava</groupId>
    <artifactId>module-b</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging> // <-- module中的packaging

    <name>module-b</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.28</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.5.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>




// 可以看出来，模块A和模块B的pom.xml高度相似
//因此，我们可以提取出共同部分作为parent：
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itranswarp.learnjava</groupId>
    <artifactId>parent</artifactId>
    <version>1.0</version>
    <packaging>pom</packaging> // <--- parent中为pom
    	// pom = project object model, 项目对象模型

    <name>parent</name> // <---- parent

    // 重复部分
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.28</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.5.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>




/*-------------------------------------------


注意到parent的<packaging>是pom而不是jar,因为parent本身不含任何Java代码。

编写parent的pom.xml只是为了在各个模块中减少重复的配置。现在我们的整个工程结构如下：

	multiple-project
	├── pom.xml
	├── parent
	│   └── pom.xml
	├── module-a
	│   ├── pom.xml
	│   └── src
	├── module-b
	│   ├── pom.xml
	│   └── src
	└── module-c
	    ├── pom.xml
	    └── src


这样模块A就可以简化为：  */
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>

    <parent> // <-- 声明parent
        <groupId>com.itranswarp.learnjava</groupId>
        <artifactId>parent</artifactId> // <-- Core
        <version>1.0</version>
        <relativePath>../parent/pom.xml</relativePath>
        	// relativePath <-- Core
    </parent>

    // Module-Self
    <artifactId>module-a</artifactId>
    <packaging>jar</packaging>
    <name>module-a</name>
</project>



/*-------------------------------------------

模块B、模块C都可以直接从parent继承，大幅简化了pom.xml的编写。

如果模块A依赖模块B，则模块A需要模块B的jar包才能正常编译，我们需要在模块A中引入模块B：  */

   ... // <-- A之前的Module-Content
    <dependencies>
        <dependency>
            <groupId>com.itranswarp.learnjava</groupId>
            <artifactId>module-b</artifactId> //<--Core
            <version>1.0</version>
        </dependency>
    </dependencies>
   ...


// 最后，在编译的时候，需要在根目录创建一个pom.xml统一编译：
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.itranswarp.learnjava</groupId>
    <artifactId>build</artifactId> 
    	// <-- /目录的pom.xml,用于统一编译
    <version>1.0</version>
    <packaging>pom</packaging> // <-- pom
    <name>build</name> // <-- name:build

    <modules> // <-- Compile which modules
        <module>parent</module> 
        <module>module-a</module>
        <module>module-b</module>
        <module>module-c</module>
    </modules>
</project>


// 这样,在根目录执行mvn clean package时, Maven根据根目录的pom.xml找到包括parent在内的共4个<module>, 一次性全部编译。


/*----------------------------------------------


#	中央仓库

其实我们使用的大多数第三方模块都是这个用法.

例如，我们使用commons logging、log4j这些第三方模块，就是第三方模块的开发者自己把编译好的jar包发布到Maven的中央仓库中。


-------------------------------


#	私有仓库

私有仓库是指公司内部如果不希望把源码和jar包放到公网上，那么可以搭建私有仓库。

私有仓库总是在【公司内部】使用，它只需要在
	【本地的~/.m2/settings.xml】

中配置好，使用方式和中央仓位没有任何区别。

----------------------------------


#	本地仓库

本地仓库是指把本地开发的项目“发布”在本地，这样其他项目可以通过本地仓库引用它。

但是我们不推荐把自己的模块安装到Maven的本地仓库，因为每次修改某个模块的源码，都需要重新安装，非常容易出现版本不一致的情况。

更好的方法是使用【模块化编译】。

在编译的时候，告诉Maven几个模块之间存在依赖关系，需要一块编译，Maven就会自动按依赖顺序编译这些模块。


-------------------------------------- */




/*========================================


#	----- 模块管理 の 小结 -----

Maven支持模块化管理，可以把一个大项目拆成几个模块：

	· 可以通过继承在parent的pom.xml统一定义重复配置；
	· 可以通过<modules>编译多个模块。


*/






















